legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
{
int i;
+#ifdef CONFIG_XEN
+ dom0_op_t op;
+ struct dom0_memory_map_entry *map;
+ unsigned long gapstart, gapsize;
+ unsigned long long last;
+#endif
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
probe_roms();
#endif
+
+#ifdef CONFIG_XEN
+ map = alloc_bootmem_low_pages(PAGE_SIZE);
+ op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
+ op.u.physical_memory_map.memory_map = map;
+ op.u.physical_memory_map.max_map_entries =
+ PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
+ BUG_ON(HYPERVISOR_dom0_op(&op));
+
+ last = 0x100000000ULL;
+ gapstart = 0x10000000;
+ gapsize = 0x400000;
+
+ for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
+ struct resource *res;
+
+ if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
+ gapsize = last - map[i].end;
+ gapstart = map[i].end;
+ }
+ if (map[i].start < last)
+ last = map[i].start;
+
+ if (map[i].end > 0x100000000ULL)
+ continue;
+ res = alloc_bootmem_low(sizeof(struct resource));
+ res->name = map[i].is_ram ? "System RAM" : "reserved";
+ res->start = map[i].start;
+ res->end = map[i].end - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ request_resource(&iomem_resource, res);
+ }
+
+ free_bootmem(__pa(map), PAGE_SIZE);
+
+ /*
+ * Start allocating dynamic PCI memory a bit into the gap,
+ * aligned up to the nearest megabyte.
+ *
+ * Question: should we try to pad it up a bit (do something
+ * like " + (gapsize >> 3)" in there too?). We now have the
+ * technology.
+ */
+ pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+ printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
+ pci_mem_start, gapstart, gapsize);
+#else
for (i = 0; i < e820.nr_map; i++) {
struct resource *res;
if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
request_resource(res, data_resource);
}
}
+#endif
}
/*
*/
static void __init register_memory(void)
{
+#ifndef CONFIG_XEN
unsigned long gapstart, gapsize;
unsigned long long last;
+#endif
int i;
+ /* Nothing to do if not running in dom0. */
+ if (!(xen_start_info->flags & SIF_INITDOMAIN))
+ return;
+
if (efi_enabled)
efi_initialize_iomem_resources(&code_resource, &data_resource);
else
legacy_init_iomem_resources(&code_resource, &data_resource);
- if (xen_start_info->flags & SIF_INITDOMAIN)
- /* EFI systems may still have VGA */
- request_resource(&iomem_resource, &video_ram_resource);
+ /* EFI systems may still have VGA */
+ request_resource(&iomem_resource, &video_ram_resource);
/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, &standard_io_resources[i]);
+#ifndef CONFIG_XEN
/*
* Search for the bigest gap in the low 32 bits of the e820
* memory space.
printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
pci_mem_start, gapstart, gapsize);
+#endif
}
/* Use inline assembly to define this because the nops are defined
}
#else /* CONFIX_XEN */
+
extern unsigned long xen_override_max_pfn;
extern union xen_start_info_union xen_start_info_union;
-/*
- * Guest physical starts from 0.
- */
+
unsigned long __init e820_end_of_ram(void)
{
unsigned long max_end_pfn = xen_start_info->nr_pages;
return xen_override_max_pfn;
}
-
-
void __init e820_reserve_resources(void)
{
- return; /* Xen won't have reserved entries */
+ dom0_op_t op;
+ struct dom0_memory_map_entry *map;
+ unsigned long gapstart, gapsize, last;
+ int i, found = 0;
+
+ if (!(xen_start_info->flags & SIF_INITDOMAIN))
+ return;
+
+ map = alloc_bootmem_low_pages(PAGE_SIZE);
+ op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
+ op.u.physical_memory_map.memory_map = map;
+ op.u.physical_memory_map.max_map_entries =
+ PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
+ BUG_ON(HYPERVISOR_dom0_op(&op));
+
+ last = 0x100000000ULL;
+ gapstart = 0x10000000;
+ gapsize = 0x400000;
+
+ for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) {
+ struct resource *res;
+
+ if ((last > map[i].end) && ((last - map[i].end) > gapsize)) {
+ gapsize = last - map[i].end;
+ gapstart = map[i].end;
+ found = 1;
+ }
+ if (map[i].start < last)
+ last = map[i].start;
+
+ if (map[i].end > 0x100000000ULL)
+ continue;
+ res = alloc_bootmem_low(sizeof(struct resource));
+ res->name = map[i].is_ram ? "System RAM" : "reserved";
+ res->start = map[i].start;
+ res->end = map[i].end - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ request_resource(&iomem_resource, res);
+ }
+
+ free_bootmem(__pa(map), PAGE_SIZE);
+
+ if (!found) {
+ HYPERVISOR_memory_op(XENMEM_maximum_ram_page, &gapstart);
+ gapstart = (gapstart << PAGE_SHIFT) + 1024*1024;
+ printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
+ KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
+ }
+
+ /*
+ * Start allocating dynamic PCI memory a bit into the gap,
+ * aligned up to the nearest megabyte.
+ *
+ * Question: should we try to pad it up a bit (do something
+ * like " + (gapsize >> 3)" in there too?). We now have the
+ * technology.
+ */
+ pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+ printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
+ pci_mem_start, gapstart, gapsize);
}
#endif
*/
__init void e820_setup_gap(void)
{
+#ifndef CONFIG_XEN
unsigned long gapstart, gapsize;
unsigned long last;
int i;
printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
+#endif
}
}
break;
+ case DOM0_PHYSICAL_MEMORY_MAP:
+ {
+ struct dom0_memory_map_entry entry;
+ int i;
+
+ for ( i = 0; i < e820.nr_map; i++ )
+ {
+ if ( i >= op->u.physical_memory_map.max_map_entries )
+ break;
+ entry.start = e820.map[i].addr;
+ entry.end = e820.map[i].addr + e820.map[i].size;
+ entry.is_ram = (e820.map[i].type == E820_RAM);
+ (void)copy_to_user(
+ &op->u.physical_memory_map.memory_map[i],
+ &entry, sizeof(entry));
+ }
+
+ op->u.physical_memory_map.nr_map_entries = i;
+ (void)copy_to_user(u_dom0_op, op, sizeof(*op));
+ }
+ break;
+
default:
ret = -ENOSYS;
-
+ break;
}
return ret;
void domain_shutdown(u8 reason)
{
struct domain *d = current->domain;
- struct vcpu *v;
-
- if(reason == SHUTDOWN_crash)
- printk("Domain %d crash detected.\n", d->domain_id);
+ struct vcpu *v;
if ( d->domain_id == 0 )
{
case XENMEM_maximum_ram_page:
if ( put_user(max_page, (unsigned long *)arg) )
return -EFAULT;
- rc = -ENOSYS;
+ rc = 0;
break;
default:
int quirk_id;
} dom0_platform_quirk_t;
+#define DOM0_PHYSICAL_MEMORY_MAP 40
+typedef struct {
+ /* IN variables. */
+ int max_map_entries;
+ /* OUT variables. */
+ int nr_map_entries;
+ struct dom0_memory_map_entry {
+ u64 start, end;
+ int is_ram;
+ } *memory_map;
+} dom0_physical_memory_map_t;
+
typedef struct {
u32 cmd;
u32 interface_version; /* DOM0_INTERFACE_VERSION */
dom0_getvcpucontext_t getvcpucontext;
dom0_getdomaininfolist_t getdomaininfolist;
dom0_platform_quirk_t platform_quirk;
+ dom0_physical_memory_map_t physical_memory_map;
} u;
} dom0_op_t;